package com.cn.lf.wx.dacs.bussiness.author.serviceImpl;

import java.util.HashMap;
import java.util.Objects;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cn.lf.wx.dacs.bussiness.author.bean.BaseException;
import com.cn.lf.wx.dacs.bussiness.author.bean.ReturnEntity;
import com.cn.lf.wx.dacs.bussiness.author.bean.SearchData;
import com.cn.lf.wx.dacs.bussiness.author.bean.SimpleUser;
import com.cn.lf.wx.dacs.bussiness.author.bean.req.ChangeUserPass;
import com.cn.lf.wx.dacs.bussiness.author.bean.req.LoginUser;
import com.cn.lf.wx.dacs.bussiness.author.dao.AuthUserMapper;
import com.cn.lf.wx.dacs.bussiness.author.entity.AuthUser;
import com.cn.lf.wx.dacs.bussiness.author.service.IAuthUserService;
import com.cn.lf.wx.dacs.bussiness.author.utils.ClaimsUtils;
import com.cn.lf.wx.dacs.bussiness.author.utils.Constant;
import com.cn.lf.wx.dacs.bussiness.author.utils.JwtUtils;
import com.cn.lf.wx.dacs.bussiness.author.utils.StringUtil;
import com.cn.lf.wx.dacs.bussiness.author.utils.UserUtil;
import com.cn.ym.log.Log;

import io.jsonwebtoken.Claims;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author jobob
 * @since 2022-03-01
 */
@Service
public class AuthUserServiceImpl extends ServiceImpl<AuthUserMapper, AuthUser> implements IAuthUserService {
	

	@Autowired
    private BCryptPasswordEncoder bCryptPasswordEncoder;

	
    @Value("${nxpcs.default.jwt.ttl}")
    private String jwtTtl;
    
    @Autowired
    protected PermissionService permission;

    @Autowired
    private AuthRoleServiceImpl authRoleServiceImpl;
    
    public ReturnEntity login(LoginUser loginUser) {
    	System.out.print("-------->("+loginUser.getAccount()+")");
        Log.info("login user === {}"+ loginUser);
        if (StringUtil.isEmpty(loginUser.getAccount())) {
            throw new BaseException("账号不能为空");
        }
        if (StringUtil.isEmpty(loginUser.getPassword())) {
            throw new BaseException("密码不能为空");
        }
//        前台传入密码时 先 MD5 加密一次
        if (loginUser.getPassword().length() != 32) {
            throw new BaseException("密码格式不正确");
        }
        
//        TODO : 判断 验证码
        AuthUser authUser = getOne(new QueryWrapper<AuthUser>().eq("account", loginUser.getAccount()));

        Log.info("authUser === {}"+authUser);
        if (Objects.isNull(authUser)) {
            throw new BaseException("账号或密码错误");
        }

//        对比密码
        boolean matches = bCryptPasswordEncoder.matches(loginUser.getPassword(), authUser.getPassword());
        if (!matches) {
            throw new BaseException("账号或密码错误");
        }

        if (Constant.DB.FLAG_TRUE.equals(authUser.getStatus())) {
            throw new BaseException("账号已禁用");
        }

//        TODO: TOKEN 得重构

        String token = UserUtil.genUserToken(getSimpleUser(authUser), Long.parseLong(jwtTtl));

        return ReturnEntity.SUCCESS("登录成功").setData(token);
    }


    public SimpleUser getSimpleUser(AuthUser user) {
        SimpleUser simpleUser = new SimpleUser();
        simpleUser.setId(user.getId());
        simpleUser.setAccount(user.getAccount());
        simpleUser.setHead(user.getHead());
        simpleUser.setName(user.getName());
        simpleUser.setStatus(user.getStatus());
        simpleUser.setRole(user.getRoleId());
        return simpleUser;
    }

    public ReturnEntity checkToken() {
    	ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        assert requestAttributes != null;
        HttpServletRequest request = requestAttributes.getRequest();
        String token = request.getHeader(Constant.Setting.HEADER_AUTH);
        HashMap<String, Object> map = new HashMap<>();
        if (!StringUtil.isEmpty(token)) {
            try {
                Claims claims = JwtUtils.parseJWT(token);
                SimpleUser authUser = ClaimsUtils.claims2User(claims);
                authUser.setToken(token);
                map.put("user", authUser);
                ReturnEntity roleMenus = authRoleServiceImpl.roleMenus(authUser.getRole().toString());
                map.put("menus", roleMenus.getData());
                return ReturnEntity.SUCCESS("已登录.").setData(map);
            } catch (Exception e) {
                e.printStackTrace();
                return ReturnEntity.NOT_LOGIN();
            }
        } else {
//            TODO:
            return ReturnEntity.NOT_LOGIN();
        }
    }

    public ReturnEntity users(SearchData searchData) {
    	System.out.println("--->" + searchData);
        IPage<AuthUser> page = new Page<AuthUser>(searchData.getCurrent(), searchData.getSize());
        QueryWrapper<AuthUser> wrapper = new QueryWrapper<>();
        wrapper.like("account", searchData.getKey()).or().like("name", searchData.getKey());
        wrapper.select(AuthUser.class, tableFieldInfo -> !Objects.equals(tableFieldInfo.getColumn(), "password"));
        IPage<AuthUser> adminUserRespIPage = page(page, wrapper);
        return ReturnEntity.SUCCESS("获取成功.").setData(adminUserRespIPage);
    }

    public ReturnEntity createUser(AuthUser user) {
        Log.info("createUser -- >  user == > " + user);

        if (StringUtil.isEmpty(user.getAccount())) {
            return ReturnEntity.FAILED("账号不能为空");
        }

        if (StringUtil.isEmpty(user.getPassword())) {
            return ReturnEntity.FAILED("密码不能为空");
        }

        if (StringUtil.isEmpty(user.getName())) {
            return ReturnEntity.FAILED("昵称不能为空");
        }

        if (StringUtil.isEmpty(user.getRoleId())) {
            return ReturnEntity.FAILED("角色不能为空");
        }
        
//        if (StringUtil.isEmpty(user.getDepartment())) {
//            return ReturnEntity.FAILED("部门不能为空");
//        }

//        判断账号是否存在
        QueryWrapper<AuthUser> qw = new QueryWrapper<>();
        qw.eq("account", user.getAccount());
        AuthUser selectOne = getOne(qw);
        if (selectOne != null) {
            return ReturnEntity.FAILED("该账号已注册");
        }

        AuthUser dbUser = new AuthUser();
        dbUser.setAccount(user.getAccount());
        dbUser.setName(user.getName());
        dbUser.setRoleId(user.getRoleId());
        dbUser.setPassword(bCryptPasswordEncoder.encode(user.getPassword()));
        dbUser.setStatus(Constant.DB.FLAG_FALSE);
        dbUser.setDeleted(Constant.DB.FLAG_FALSE);
        
        if (save(dbUser)) {
            return ReturnEntity.SUCCESS("注册成功");
        }
        return ReturnEntity.FAILED("注册失败");
    }

    public ReturnEntity changeUser(AuthUser user) {
        Log.info("changeUser -- > user == >" + user);

//        判断账号是否存在
        QueryWrapper<AuthUser> qw = new QueryWrapper<>();
        qw.eq("account", user.getAccount());
        qw.ne("id", user.getId());
        AuthUser selectOne = getOne(qw);
        if (Objects.nonNull(selectOne)) {
            return ReturnEntity.FAILED("该账号已注册");
        }
        user.setPassword(null);
        if (updateById(user)) {
            return ReturnEntity.SUCCESS("修改成功");
        }

        return ReturnEntity.FAILED("修改失败");
    }

    public ReturnEntity changeUserStatus(AuthUser user) {
        String RetText = Constant.DB.FLAG_TRUE.equals(user.getStatus()) ? "禁用" : "启用";

        if (StringUtil.isEmpty(user.getId())) {
            return ReturnEntity.FAILED("用户id为空");
        }

        if (Constant.DB.FLAG_TRUE.equals(user.getStatus())) {
            user.setStatus(Constant.DB.FLAG_FALSE);
        } else {
            user.setStatus(Constant.DB.FLAG_TRUE);
        }

        if (updateById(user)) {
            return ReturnEntity.SUCCESS(RetText + "成功");
        }

        return ReturnEntity.FAILED(RetText + "失败");
    }

    public ReturnEntity changeUserPass(ChangeUserPass changeUserPass) {
//        修改密码
        SimpleUser simpleUser = permission.checkUser();
        if (!simpleUser.getId().equals(changeUserPass.getUid())) {
            return ReturnEntity.FAILED("用户不一致");
        }

        AuthUser adminDb = getById(simpleUser.getId());

        boolean matches = bCryptPasswordEncoder.matches(changeUserPass.getOldPass(), adminDb.getPassword());
        
        if (!matches) {
            return ReturnEntity.FAILED("当前密码错误");
        }

        if (!changeUserPass.getNewPass().equals(changeUserPass.getRepeatPass())) {
            return ReturnEntity.FAILED("两次输入的密码不一致");
        }
        AuthUser user = new AuthUser();
        user.setId(adminDb.getId());
        user.setPassword(bCryptPasswordEncoder.encode(changeUserPass.getRepeatPass()));
        if (updateById(user)) {
            return ReturnEntity.SUCCESS("修改成功");
        }
        return ReturnEntity.FAILED("修改失败");
    }
}
